#!/bin/bash
#pMusic - add track to playqueue
#GPL - Copyright Sigmund Berglund

[[ "$PTR_BTN" = @"2|3" ]] && exit #right-click menu or play from sourcelist
export TEXTDOMAIN=pmusic
export OUTPUT_CHARSET=UTF-8
$APPDIR/func -reset_gtk

check_source (){
	#check if exist
	if [ ! -s "$SOURCE" ]; then
		grep -F "${SOURCE##*/}|" "$STORAGE_DIR/index_mymusic" | cut -d'|' -f14 | grep -vFm1 "$SOURCE" > $WORKDIR/SOURCE_ALT
		if [ ! -s "$(<$WORKDIR/SOURCE_ALT)" ]; then #if basename is in db, pMusic will search for alternative path.
			echo > $WORKDIR/flag_fix_db #avoid quick_index-msg at next check_source.
			fix_db
			exit
		fi
	elif [ -f $WORKDIR/flag_fix_db ]; then
		rm $WORKDIR/flag_fix_db
	#if not in db, allow update of database
	elif [ ! "$(grep -F "$SOURCE" "$STORAGE_DIR/index_mymusic")" ]; then
		#if scan already is running, exit
		read TMP < $WORKDIR/maingui_notebook_page
		[[ ${TMP} = 2 ]] && exit
		#---
		echo "$SOURCE" > $WORKDIR/source_checked
		echo 1 > $WORKDIR/maingui_notebook_page
		cp -f "$APPDIR/themes/$THEME/question.svg" $WORKDIR/albumart.jpg
		for I in 1 2 3 4 5 6; do #in case gui is not running --> wait before setting the <notebook> page.
			[ ! -f $WORKDIR/gui_is_running ] && break || sleep 1
		done
		echo true > $WORKDIR/UPDATE_GUI
	fi
}

export -f check_source

fix_db (){
SOURCE=${SOURCE#[0-9]*:}
export box='
<window title="pMusic" icon-name="pmusic" window_position="2">
<vbox space-expand="false" space-fill="false">
 <frame>
  <pixmap icon_size="6" space-expand="false" space-fill="false"><input file stock="gtk-dialog-question"></input></pixmap>
  <text use-markup="true" space-expand="false" space-fill="false"><label>"<b>'$(gettext 'File found in database does not exist')':</b>"</label></text>
  <text use-markup="true" space-expand="false" space-fill="false"><label>"<small><small>'${SOURCE}'</small></small>


'$(gettext 'What occurred?')'"</label></text>
 </frame>
 <vbox space-expand="true" space-fill="true">
  <hbox space-expand="false" space-fill="false">
   <entry accept="file" fs-title="pMusic" space-expand="true" space-fill="true">
    <variable>MOVE_FILE</variable>
    <input>echo "'$SOURCE'"</input>
   </entry>
   <button space-expand="false" space-fill="false">
    <input file stock="gtk-open"></input>
    <action type="fileselect">MOVE_FILE</action>
    <variable>BUTTON_MOVE_FILE</variable>
   </button>
   <sensitive>false</sensitive>
   <variable>HBOX_MOVE_FILE</variable>
  </hbox>
  <hbox visible="false" space-expand="false" space-fill="false">
   <entry accept="directory" fs-title="pMusic" space-expand="true" space-fill="true">
    <variable>MOVE_DIR</variable>
    <input>dirname "'$SOURCE'"</input>
   </entry>
   <button space-expand="false" space-fill="false">
    <input file stock="gtk-open"></input>
    <action type="fileselect">MOVE_DIR</action>
    <variable>BUTTON_MOVE_DIR</variable>
   </button>
   <sensitive>false</sensitive>
   <variable>HBOX_MOVE_DIR</variable>
  </hbox>
  
  <radiobutton visible="false"></radiobutton>
  <radiobutton space-expand="false" space-fill="false">
   <variable>RADIO_MOVE_FILE</variable>
   <label>"'$(gettext 'File has been moved to')'..."</label>
   <action>if true enable:HBOX_MOVE_FILE</action>
   <action>hide:HBOX_MOVE_DIR</action>
   <action>show:HBOX_MOVE_FILE</action>
   <action>enable:BUTTON_FIX</action>
  </radiobutton>
  <radiobutton space-expand="false" space-fill="false">
   <variable>RADIO_MOVE_DIR</variable>
   <label>"'$(gettext 'Complete directory has been moved to')'..."</label>
   <action>if true enable:HBOX_MOVE_DIR</action>
   <action>hide:HBOX_MOVE_FILE</action>
   <action>show:HBOX_MOVE_DIR</action>
   <action>enable:BUTTON_FIX</action>
  </radiobutton>
  <radiobutton space-expand="false" space-fill="false">
   <variable>RADIO_DELETE</variable>
   <label>"'$(gettext 'File has been deleted')'"</label>
   <action>if true disable:HBOX_MOVE_FILE</action>
   <action>if true disable:HBOX_MOVE_DIR</action>
   <action>enable:BUTTON_FIX</action>
  </radiobutton>
 </vbox>
   
 <hbox>
  <vbox space-expand="false" space-fill="false">
   <text space-expand="true" space-fill="true"><label>""</label></text>
   <hbox space-expand="false" space-fill="false">
    <button cancel></button>
    <button space-expand="false" space-fill="false">
     <input file icon="gtk-refresh"></input>
     <label>" '$(gettext 'Update the entire pMusic database')'"</label>
     <action>'$APPDIR'/func_index -update_index &</action>
     <action type="exit">EXIT</action>
    </button>
   </hbox>
  </vbox>
  <text space-expand="true" space-fill="true"><label>""</label></text>
  <button image-position="2" height-request="70" space-expand="false" space-fill="false">
   <variable>BUTTON_FIX</variable>
   <input file icon="gtk-apply"></input>
   <label>"     '$(gettext 'Fix it')'     "</label>
   <sensitive>false</sensitive>
   <action type="exit">update_db</action>
  </button>
 </hbox>
</vbox>
</window>'
I=$IFS; IFS=""
for STATEMENTS in  $($GTKDIALOG -p box); do
	eval $STATEMENTS
done
IFS=$I

if [ $RADIO_MOVE_FILE = true ]; then
	if [ -f "$MOVE_FILE" ]; then
		( flock -e 200
			grep -aF "$SOURCE" "$STORAGE_DIR/index_mymusic" | awk -F'|' -v VAR1="$MOVE_FILE" '{print VAR1 "|" $2 "|" $3 "|" $4 "|" $5 "|" $6 "|" $7 "|" $8 "|" $9 "|" $10 "|" $11 "|" $12 "|" $13 "|" VAR1 "|" $15 "|" $16 "|" $17 "|" $18 "|" $19 "|" $20 "|" $21}' > $WORKDIR/tmp_update_db
			grep -aFv "$SOURCE" "$STORAGE_DIR/index_mymusic" >> $WORKDIR/tmp_update_db
			mv $WORKDIR/tmp_update_db "$STORAGE_DIR/index_mymusic"
		) 200>$WORKDIR/mymusic_db.lockfile 
		#update sourcelist
		echo "sed -i \"s%$SOURCE%$MOVE_FILE%\" $WORKDIR/sourcelist" > $WORKDIR/exec
		echo "sed -i \"s%$SOURCE%$MOVE_FILE%\" \"$STORAGE_DIR/favorites\"" > $WORKDIR/exec
		sed -i -e 's/\&/\\\&/g' -e 's/\[/\\\[/g' -e 's/\]/\\\]/g' -e s/\`/\\\\\`/g $WORKDIR/exec
		chmod 722 $WORKDIR/exec
		$WORKDIR/exec
	else
		TXT1="$(gettext 'File does not exist')"
		. $APPDIR/box_ok
	fi
elif [ $RADIO_MOVE_DIR = true ]; then
	if [ -d "$MOVE_DIR" ]; then
		OLD_DIR="`dirname "$SOURCE"`"
		grep -aF "$OLD_DIR" "$STORAGE_DIR/index_mymusic" > $WORKDIR/tmp_update_db1
		#check if target sounds logical
		TMP="`basename "$SOURCE"`"
		if [ ! -f "${MOVE_DIR}/${TMP}" ]; then
			TXT1="$(gettext "Nope, this can't be the correct directory, No such files found.")"
			. $APPDIR/box_ok
			exit
		fi
		#---
		echo "$(gettext 'Redefining database')." > $WORKDIR/splashtext
		$APPDIR/box_splash &

		( flock -e 200
			grep -aFv "$OLD_DIR" "$STORAGE_DIR/index_mymusic" > $WORKDIR/tmp_update_db
			while read I; do
				FILENAME=${I%%|*}; FILENAME=${##*/}
				echo "$I" | awk -F'|' -v VAR1="${MOVE_DIR}/${FILENAME}" '{print VAR1 "|" $2 "|" $3 "|" $4 "|" $5 "|" $6 "|" $7 "|" $8 "|" $9 "|" $10 "|" $11 "|" $12 "|" $13 "|" VAR1 "|" $15 "|" $16 "|" $17 "|" $18 "|" $19 "|" $20 "|" $21}' >> $WORKDIR/tmp_update_db
				
			done < $WORKDIR/tmp_update_db1
			sort -ust'|' -k1,1 -o $WORKDIR/tmp_update_db2 $WORKDIR/tmp_update_db

		    mv "$STORAGE_DIR/index_mymusic" "$STORAGE_DIR/index_mymusic.bak"
			mv $WORKDIR/tmp_update_db2 "$STORAGE_DIR/index_mymusic"
		) 200>$WORKDIR/mymusic_db.lockfile
		echo 100 > $WORKDIR/splash #reset progress bar
		#update gui
		echo "sed -i \"s%$OLD_DIR%$MOVE_DIR%g\" $WORKDIR/sourcelist" > $WORKDIR/exec
		echo "sed -i \"s%$OLD_DIR%$MOVE_DIR%g\" \"$STORAGE_DIR/favorites\"" > $WORKDIR/exec
		echo "sed -i \"s%$OLD_DIR%$MOVE_DIR%g\" $WORKDIR/trackinfo_album" > $WORKDIR/exec #album-tab
		sed -i -e 's/\&/\\\&/g' -e 's/\[/\\\[/g' -e 's/\]/\\\]/g' -e s/\`/\\\\\`/g $WORKDIR/exec
		chmod 722 $WORKDIR/exec
		$WORKDIR/exec
	else
		TXT1="$(gettext 'Directory does not exist')"
		. $APPDIR/box_ok
	fi
elif [ $RADIO_DELETE = true ]; then
	#remove from db
	( flock -e 200
		grep -avF "$SOURCE" "$STORAGE_DIR/index_mymusic" > $WORKDIR/tmp_radio_del
		mv $WORKDIR/tmp_radio_del "$STORAGE_DIR/index_mymusic"
	) 200>$WORKDIR/mymusic_db.lockfile 
	#remove from sourcelist
	grep -vF "$SOURCE" $WORKDIR/sourcelist > $WORKDIR/tmp_add
	mv $WORKDIR/tmp_add $WORKDIR/sourcelist
	#remove from bookmarks
	grep -v "|$SOURCE$" "$STORAGE_DIR/favorites" > $WORKDIR/tmp_add
	mv -f $WORKDIR/tmp_add "$STORAGE_DIR/favorites"
	#remove from playqueue
	grep -v "|${SOURCE}|" $WORKDIR/playlist > $WORKDIR/tmp_add
	mv -f $WORKDIR/tmp_add $WORKDIR/playlist
	echo true | tee $WORKDIR/UPDATE_GUI $WORKDIR/UPDATE_PLAYLIST
fi
echo true > $WORKDIR/UPDATE_SOURCELIST
echo true > $WORKDIR/UPDATE_TRACKINFO
}

export -f fix_db

case "$1" in
-check_source)
	check_source
	;;
-fix_db)
	fix_db
	;;
-smartadd)
	echo "$(gettext 'Add more')..." > $WORKDIR/splashtext
	$APPDIR/box_splash progress &
	. $CONFIG #filter values is saved to config in external window
	SMARTADD_NR=$2
	SMARTADD_RANDOM=$3
	SMARTADD_SOURCE=$4
	AUDIO_FORMATS2="${AUDIO_FORMATS//$/\\|}" #example: |/path/file.mp3|
	#what is add source
	if [ "$SMARTADD_SOURCE" = "$(gettext 'My music (DB)')" ]; then
		if [ $SMARTADD_RATE -ge 1 ]; then #rating is set
			echo "$(gettext 'Search rated tracks in DB')" > $WORKDIR/splashtext
			$APPDIR/func_rating -buildlist 1 "$STORAGE_DIR/index_mymusic" 0 $SMARTADD_RATE > $WORKDIR/tmp_smartadd_input
		else
			ln -sf "$STORAGE_DIR/index_mymusic" $WORKDIR/tmp_smartadd_input
		fi
	else #sourcelist
		if [ $SMARTADD_RATE -ge 1 ]; then #rating is set 
			#sourcelist may not have rating info (ie. when browsing). If so, we use db
			if [ ! "`grep -iE "$AUDIO_FORMATS2|cdda:|://" $WORKDIR/sourcelist |  cut -d'|' -f9 | sort -rns | head -n1`" ] ; then
				cut -d'|' -f1 $WORKDIR/sourcelist | cut -d: -f2- | grep -iE "$AUDIO_FORMATS|cdda:|://" > $WORKDIR/tmp_smartadd
				while read I; do
					grep -Fm1 "$I" "$STORAGE_DIR/index_mymusic" >> $WORKDIR/tmp_smartadd2
				done < $WORKDIR/tmp_smartadd
				if [ -s $WORKDIR/tmp_smartadd2 ]; then
					$APPDIR/func_rating -buildlist 1 $WORKDIR/tmp_smartadd2 0 $SMARTADD_RATE > $WORKDIR/tmp_smartadd_input
				else
					echo 100 > $WORKDIR/splash #reset progress bar
					exit
				fi
			else #rating exist in sourcelist
				grep -iE "$AUDIO_FORMATS2|cdda:|://" $WORKDIR/sourcelist | sort -rnst'|' -k 9,9 > $WORKDIR/tmp_smartadd
				while read I; do
					if [ "`cut -d'|' -f9 <<< "$I"`" -lt $SMARTADD_RATE ]; then
						break
					else
						echo "$I" >> $WORKDIR/tmp_smartadd_input
					fi
				done < $WORKDIR/tmp_smartadd
			fi
		else
			grep -iE "$AUDIO_FORMATS2|cdda:|://" $WORKDIR/sourcelist > $WORKDIR/tmp_smartadd_input
		fi
	fi

	#filters
	if [ $SMARTADD_BPM_LO -ge 1 ] && [ -s $WORKDIR/tmp_smartadd_input ]; then #tempo
		awk -F '|' -v TS1=$SMARTADD_BPM_LO -v TS2=$SMARTADD_BPM_HI '{ if ($13 >= TS1 && $13 <= TS2) print }' $WORKDIR/tmp_smartadd_input > $WORKDIR/tmp_smartadd_input1
		mv -f $WORKDIR/tmp_smartadd_input1 $WORKDIR/tmp_smartadd_input
	fi

	if [ "$SMARTADD_GENRE" ] && [ -s $WORKDIR/tmp_smartadd_input ]; then #genre
		awk -F '|' -v TS1="$SMARTADD_GENRE" '$7 ~ TS1 { print }' $WORKDIR/tmp_smartadd_input > $WORKDIR/tmp_smartadd_input1
		mv -f $WORKDIR/tmp_smartadd_input1 $WORKDIR/tmp_smartadd_input
	fi
	
	#check if filtering has been too strict
	if [ ! -s $WORKDIR/tmp_smartadd_input ]; then
		echo 100 > $WORKDIR/splash #reset progress bar
		TXT1="<b>$(gettext 'No files to add')</b>"
		TXT2="$(gettext 'Is filtering set too strict?')"
		. $APPDIR/box_ok
		exit
	fi

	#specify total numbers in list
	n=`grep -c ^ $WORKDIR/tmp_smartadd_input` #also used in random seed
	if [ $SMARTADD_NR -gt $n ] && [ $SMARTADD_RANDOM = false ]; then SMARTADD_NR=$n; fi
	[ "$SMARTADD_NR" = "$(gettext 'All')" ] && SMARTADD_NR=$n
	[ ! $SMARTADD_NR -gt 0 ] && SMARTADD_NR=1 #in case no valid number
	#What limits the number of tracks to add
	if [ $SMARTADD_RANDOM = true ]; then #if adding randomly, only $SMARTADD_NR is the limit
		echo -n > $WORKDIR/tmp_smartadd_input2
		for I in $(seq 1 $SMARTADD_NR); do echo 'pmusic_smartadd' >> $WORKDIR/tmp_smartadd_input2; done
	else #if adding by sort order, the input file is the limitation
		ln -s $WORKDIR/tmp_smartadd_input $WORKDIR/tmp_smartadd_input2
	fi
	#---
	COUNT=1
	echo -n > $WORKDIR/pmusic.add
	while read J; do
		if [ $SMARTADD_RANDOM = true ]; then
			#here it might be a playlist file (because random doesn't define target until here)
			while [ K = K ]; do 
				r=$((RANDOM % n))
				r=$(($r+1))
				I="`cut -d'|' -f1 $WORKDIR/tmp_smartadd_input | head -n $r | tail -n 1`"
				[[ "$I" != @(*pmu|*pmd|*m3u|*pls) ]] && break
			done 
		else
			I=${J%%|*}
		fi
		case $I in [0-9]*) I=${I#*:};; esac #remove unique source-nr
		#look in index for extra info
		IFS='|' read ADR ARTIST TITLE ALBUM NR YEAR GENRE COMMENT RATING FORMAT BITRATE LENGTH TMP <<< "$(grep -Fm1 "$I" $WORKDIR/tmp_smartadd_input)"
		case $I in
			*://*) [ ! "$LENGTH" ] && LENGTH="`$APPDIR/func_C -sec2time $COMMENT`";; #jamendo is a bit out of standard
			*) ARTIST=${ARTIST//\ \ \ \ /};; #removal of the 4 spaces is in case of expanded album
		esac
		[ "$TITLE" ] && echo "$LENGTH|$ARTIST - $TITLE|$I" >> $WORKDIR/pmusic.add || echo "$LENGTH|$ARTIST|$I" >> $WORKDIR/pmusic.add
		[ $COUNT -ge $SMARTADD_NR ] && break
		COUNT=$(($COUNT+1))
	done <<< "$(grep -iE "$AUDIO_FORMATS2|cdda:|http:|https:|pmusic_smartadd" $WORKDIR/tmp_smartadd_input2)"
	rm $WORKDIR/tmp_smartadd*
	echo 100 > $WORKDIR/splash #reset progress bar
	$APPDIR/func_add -add $WORKDIR/pmusic.add
	$APPDIR/func_config -write_config #save smartadd settings
	;;

-add)
	[ "$2" ] && SOURCE="$2"
	[ -d "${SOURCE}" ] && exit #directory - browse instead of add
	rm -f $WORKDIR/history #reset undo/redo function
	read ADDMODE < $WORKDIR/ADDMODE #add to tail or as next track
	#check for timestamp from bookmark
	if [[ ${SOURCE} = *?:??]* ]]; then
		TIME=${SOURCE%%]*}; TIME=${TIME#*[}
		SOURCE=${SOURCE#*] }
		echo "$[(${TIME%%:*}*60)+${TIME#*:}]" > $WORKDIR/SS
		echo true > $WORKDIR/TIMESTAMP
		ENSURE_PLAY=true #playlist has no internal structure to handle timestamps. --> must play imediatly
	fi
	#ENSURE_PLAY is also defined by the -P switch. 
	if [ "$ENSURE_PLAY" = "true" ]; then
		$APPDIR/func_store_playlist
		$APPDIR/func -new
	fi
	#if nothing is playing or adding first track to playlist, play added song. NOTE!, this also happens if track is paused.
	if [ ! -s $WORKDIR/AUTOPLAY ]; then #if exist, another add-instance is working as well as this one
		PS="`LC_ALL=C ps -eo pid,s,command`"
		[[ "$PS" != *aplay* || "$PS" = *' T aplay'* || ! -s $WORKDIR/playlist ]] && echo true > $WORKDIR/AUTOPLAY
	fi
	#read input
	case $SOURCE in
	pmusicbrowse_*)	exit ;; #these will be executed in -func -browse. The difference is that refresh of sourcelist is made at once. Not via timer as for actions here in func_add.
	pmusic_*) #redirect all navigations here for speed reasons
		case $SOURCE in 
			*_history)				$APPDIR/func -index_history							;;
			*_history:*)			SEARCH="`echo "$SOURCE" | cut -d: -f2- | cut -d'|' -f1`"
									cp -f "$STORAGE_DIR"/history_files/$SEARCH $WORKDIR/sourcelist
									echo true > $WORKDIR/UPDATE_SOURCELIST				;;
			*_file_search)			$APPDIR/func -pfilesearch							;;
			*_index)				$APPDIR/func_index -update_index					;;
			*_songs)				$APPDIR/func -index_songs							;;
			*_collections)			$APPDIR/func -index_playlists						;;
			*_radiohits)			$APPDIR/func_radiohits								;; 
			*_radiohits:*)			SOURCE="`echo "$SOURCE" | cut -d: -f2-`"
									$APPDIR/func -browse_radiohits "$SOURCE"			;; 
			*_radio)				$APPDIR/func_radio									;;
			*_radio_country)		$APPDIR/func -radio -country						;;
			*_radio_genre)			$APPDIR/func -radio -genre							;;
			*_rating)				$APPDIR/func_rating -custom							;;
			*_rating_month)			echo "|$(gettext 'Searching last month')..." > $WORKDIR/sourcelist
									echo true > $WORKDIR/UPDATE_SOURCELIST
									$APPDIR/func_rating -buildlist "$(($(date +%s)-2592000))" "$STORAGE_DIR/index_mymusic" > $WORKDIR/tmp
									sort -rnst"|" -k9,9 $WORKDIR/tmp | grep -vF "|0|" > $WORKDIR/sourcelist
									echo true > $WORKDIR/UPDATE_SOURCELIST				;;
			*_podcast)				$APPDIR/func_podcast -setup -index					;;
			*_podcast_setup)		$APPDIR/func_podcast -setup							;;
			*_podcast_show)			$APPDIR/func_podcast -show_podcast
									echo true > $WORKDIR/UPDATE_SOURCELIST				;;
			*_recent)				$APPDIR/func -index_recent							;;
			*_cd_audio)				$APPDIR/func_cd -read_cd							;;
			*_bookmarks)			$APPDIR/func_bookmarks -manage_bookmarks			;;
			*_jamendo_manager)		$APPDIR/func_jamendo -jamendo_manager				;;
			*_jamendo)				$APPDIR/func_jamendo -jamendo						;; 
			*_jamendo_char*)		$APPDIR/func_jamendo -jamendo_char ${SOURCE##*:}	;; 
			*_jamendo_back)			$APPDIR/func_jamendo -jamendo_back					;; 
			*_jamendo_artist*)		$APPDIR/func_jamendo -jamendo_artist ${SOURCE#*:}	;; 
			*_jamendo_album*)		SOURCE=${SOURCE#*:}
									[ "$SOURCE" = "youtube" ] && $APPDIR/func_jamendo -jamendo || $APPDIR/func_jamendo -jamendo_album "$SOURCE";;
		esac
		exit
		;;
	*cdda:*)
		case $SOURCE in [0-9]*) SOURCE="$(cut -c 10- <<< "$SOURCE")";; esac #remove unique source-nr before adding
		echo "||$SOURCE" > $WORKDIR/songs_in_list
		;;
	*http://*|*https://*|*mms://*|*:+[0-9]*) #streaming
		if [ "`grep -F "$SOURCE" $WORKDIR/sourcelist | cut -d'|' -f1 | grep -F 'http'`" ]; then #url in sourcelist
			IFS='|' read COMMAND ARTIST TITLE ALBUM NR YEAR GENRE COMMENT RATING FORMAT BITRATE LENGTH COL13 ADR ICON <<< "`grep -Fm1 "$SOURCE" $WORKDIR/sourcelist`"
			ARTIST=${ARTIST//\ \ \ \ /} #removal of the 4 spaces is in case of expanded list
			[[ "$TITLE" = *]http* ]] && TITLE=${TITLE#*]} #if add bookmark with timestamp from sourcelist
			[[ ! "$LENGTH" && $COMMAND = *jamendo.com* ]] && LENGTH="`grep -Fm1 "$SOURCE" $WORKDIR/sourcelist | cut -d'|' -f8`" #jamendo Top100 doesn't follow the standard fully, and places length in column 8 (because no option of blank columns at download). 
			case $LENGTH in
				*[0-9]:*) false;; #correct syntax (mm:ss) ie. from jamendo index
				*[0-9]*) LENGTH=`$APPDIR/func_C -sec2time $LENGTH`;; #transform sec to a human readable length
				*) LENGTH='00:00'; RADIO=true;;
			esac
			[[ "$SOURCE" = "+[0-9]"* ]] && SOURCE=${SOURCE/+/https://storage-new.newjamendo.com/tracks/}_96.mp3 || SOURCE=${SOURCE#[0-9]*:} #URL in jamendo index is stripped
			if	[[ "$TITLE" && ${RADIO} != "true" ]]; then	NAME="$ARTIST - $TITLE" #title column in radio_index holds the genre tag. $RADIO i set 4 lines above
			elif [ "$ARTIST" ]; then						NAME="$ARTIST"
			else											NAME="$SOURCE"
			fi
			#in case of timestamp, remove it from $NAME
			read TMP < $WORKDIR/TIMESTAMP
			[ "$TMP" = "true" ] && NAME=${NAME#*]\ }
			#---
			echo "$LENGTH|$NAME|$SOURCE" > $WORKDIR/songs_in_list
			#if we are inside the radio frontend we want to play the stream straight away
			if [[ "$PMUSIC_FRONTEND" = *'/.Radio'* ]]; then
				$APPDIR/func -new
				echo true > $WORKDIR/AUTOPLAY
			fi
		else #add url from search-field
			echo "00:00||$SOURCE|" > $WORKDIR/songs_in_list
		fi
		USE_META=false
		;;
	*.m3u)
		check_source &
		echo "$SOURCE" > $WORKDIR/last_added_playlist
		echo -n > $WORKDIR/songs_in_list
		while read I; do
			case $I in
				'#EXTM3U'*|'#M3U'*) #header info. We don't use this
					continue
					;;
				'#EXT'*)
					#we use #EXT info in m3u if available
					LENGTH=${I#*:}; LENGTH=${LENGTH%%,*}
					[ "$LENGTH" -gt 0 ] || LENGTH='' && LENGTH=`$APPDIR/func_C -sec2time $LENGTH` #m3u stores length in seconds, we want a human readable length
					NAME=${I#*,}
					continue #if EXT line, go to next line...
					;;
				cdda:*|*/*) #Adress (path/URL)
					ADR="$I"
					;;
				*) #no path for files in list. Use current dir
					ADR="${SOURCE%/*}/$I"
					;;
			esac
			echo "$LENGTH|$NAME|$ADR" | tr -d '\r' >> $WORKDIR/songs_in_list #tr is removing carriage return
		done < "$SOURCE"
		;;
	*.pls)
		check_source &
		echo "$SOURCE" > $WORKDIR/last_added_playlist
		echo -n > $WORKDIR/songs_in_list
		while read I; do
			NR=${I%%=*}; NR=${NR#*e}
			ADR=${I#*=}
			#length
			IFS='=' read C1 LENGTH <<< "`grep -F "Length${NR}=" "$SOURCE"`"
			[ "$LENGTH" -gt 0 ] || LENGTH='' && LENGTH=`$APPDIR/func_C -sec2time $LENGTH` #pls stores length in seconds, we want a human readable length
			#---
			IFS='=' read C1 NAME <<< "`grep -F "Title${NR}=" "$SOURCE"`"
			[ ! "$NAME" ] && NAME=${ADR##*/}
			echo "$LENGTH|$NAME|$ADR" >> $WORKDIR/songs_in_list #tr is removing carriage return
		done <<< "$(grep "^File" "$SOURCE")"
		;;
	*.asx)
		check_source &
		#splash if playlist contains more than 1 entries
		if [ `grep -Fi 'href=' "$SOURCE" | wc -l` -ge 3 ]; then
			echo "$(gettext 'Importing playlist')..." > $WORKDIR/splashtext
			$APPDIR/box_splash progress &
		fi
		#---
		echo "$SOURCE" > $WORKDIR/last_added_playlist
		echo -n > $WORKDIR/songs_in_list
		while read I; do
			[ ! "`grep -Fi 'href=' <<< "$I"`" ] && continue
			ADR="`cut -d'"' -f2 <<< "$I" | awk -F 'file://' '{print $2}'`"
			echo "||$ADR" | tr -d '\r' >> $WORKDIR/songs_in_list #tr is removing carriage return
		done < "$SOURCE"
		;;
	*.add) #internal (ie. add directory from cli)
		grep -E "\|/|cdda:" "$SOURCE" > $WORKDIR/songs_in_list
		;;
	*.pmd)
		$APPDIR/func -check_playlist "$SOURCE" & #check paths of tracks in list
		echo -n > $WORKDIR/songs_in_list
		I=$IFS; IFS='|'
		while read ADR ARTIST TITLE ALBUM NR YEAR GENRE COMMENT RATING FORMAT BITRATE LENGTH TMP; do
			NAME="$ARTIST - $TITLE"
			echo "$LENGTH|$NAME|$ADR" >> $WORKDIR/songs_in_list
		done < "$SOURCE"
		IFS=$I
		;;
	*.pmu)
		check_source & #check if pmu exist in db
		$APPDIR/func -check_playlist "$SOURCE" & #check paths of tracks in list
		echo "$SOURCE" > $WORKDIR/last_added_playlist
		#since *.pmu is the native format, we just drop directly into list 
		if [[ ${ADDMODE} = "next" && -s $WORKDIR/PLAYLIST ]]; then #add the song after selection. This is slower, so do not use for multiple adds.
			( flock -e 201
				LINE_SELECTED="`grep -m1 "$(<$WORKDIR/PLAYLIST)" $WORKDIR/playlist`"
				grep -w -B100000 "$LINE_SELECTED" $WORKDIR/playlist > $WORKDIR/tmp_add
				cat "$SOURCE" >> $WORKDIR/tmp_add
				grep -w -A100000 "$LINE_SELECTED" $WORKDIR/playlist | tac | head -n -1 | tac >> $WORKDIR/tmp_add
				mv $WORKDIR/tmp_add $WORKDIR/playlist
			) 201>$WORKDIR/playlist.lockfile 
		else #add at the end of list
			( flock -e 201
				cat "$SOURCE" >> $WORKDIR/playlist
			) 201>$WORKDIR/playlist.lockfile
		fi
		#play added song if autoplay is activated earlier in this script.
		if [ -s $WORKDIR/AUTOPLAY ]; then
			IFS='|' read C1 C2 C3 TMP C < "$SOURCE"
			$APPDIR/func_player -play "$TMP" -autoplay &
		fi
		$APPDIR/func -statusbar_playlist & #update statusbar
		echo -n > $WORKDIR/songs_in_list #no more to add
		echo true | tee $WORKDIR/UPDATE_GUI $WORKDIR/UPDATE_PLAYLIST
		;;
	*/*.mid|*/*.kar) #internal 
		SOURCE=${SOURCE#[0-9]*:} #remove unique source-nr
		check_source &
		LENGTH="`grep -Fm1 "$SOURCE" "$STORAGE_DIR"/index_mymusic | cut -d'|' -f12`"
		if [ ! "$LENGTH" ]; then
			TMP="`timidity -OuM8 -o $WORKDIR/tmp_midi.au "$SOURCE" | grep -F 'Playing time' | cut -d'~' -f2 | cut -d' ' -f1`" #seconds
			LENGTH=`$APPDIR/func_C -sec2time $TMP`
		fi
		echo "$LENGTH|${SOURCE##*/}|$SOURCE|`date +%s%N` $SOURCE" > $WORKDIR/songs_in_list
		;;
	*/*) #single file. Also accepts file:// 
		SOURCE=${SOURCE#[0-9]*:} #remove unique source-nr
		check_source &
		LENGTH="`grep -Fm1 "$SOURCE" "$STORAGE_DIR"/index_mymusic | cut -d'|' -f12`"
		echo "$LENGTH||$SOURCE" > $WORKDIR/songs_in_list
		;;
	*) #search string
		SEARCH="$SOURCE"
		. $APPDIR/func -search_refresh
		exit
		;;
	esac
	#for progress bar
	COUNT=1
	TOTAL=`grep -c ^ $WORKDIR/songs_in_list`
	#---
	cp -f $WORKDIR/playlist $WORKDIR/tmp_playlist
	#add
	while IFS='|' read LENGTH NAME ADR EXEC; do
		### N A M E ###
		if [ ! "$NAME" ]; then
			#use metatag or filename in playlist
			if [ "$USE_META" = "true" ]; then
				case $ADR in
					*cdda:*) #CD audio
						NAME=${ADR##*:}
						;;
					*)
						. $APPDIR/func_id3io "$ADR" -read
						if [ "$ARTIST" ] && [ "$TITLE" ]; then		NAME="$ARTIST - $TITLE"
						elif [ "$ARTIST" ] || [ "$TITLE" ]; then	NAME="${ARTIST}${TITLE}"
						else										NAME=${ADR##*/}; NAME=${NAME%.*}
						fi
						;;
				esac
			else #use filename
				case $ADR in
					/*) NAME=${ADR##*/} #basename
						NAME=${NAME%.*} #skip extension
						;;
					*://*) #URL
						NAME="$ADR"
						TMP="`grep -F "$ADR" "$STORAGE_DIR/index_radio"`"
						if [ "$TMP" ]; then #radio index
							IFS='|' read C1 NAME C <<< "$TMP"
						else #look in favorites
							TMP="`grep -F "$ADR" "$STORAGE_DIR/favorites"`"
							[ "$TMP" ] && NAME="`echo ${TMP%%|*} | awk '{print $2}'`"
						fi
						;;
					*cdda:*) #CD audio
						NAME=${ADR##*:}
						;;
				esac
			fi
		fi
		#convert underscores and %20 --- index_recent may contain (CD) or (www) - remove
		N=${NAME//_/ }; N=${N//%20/ }; N=${N// (CD)/}; NAME=${N// (www)/}
		### L E N G T H ###
		if [ ! "$LENGTH" ]; then
			case $ADR in 
				*cdda:*)
					LENGTH="`echo "${ADR// /}" | cut -d: -f3-4`"
					;;
				*)
					LENGTH=$(ffmpeg -i "$ADR" 2>&1 | grep -F Duration | awk '{print $2}' | cut -d"." -f1)
					case $LENGTH in
						00:*) #hours is zero
							LENGTH=${LENGTH#*:}
							;;
						[0-9][0-9]:*:*) #time is above 59:59 --> convert it to 2 columns instead of 3
							IFS=: read H M S <<< "$LENGTH"
							M=$(((10#$H * 60) + 10#$M))
							LENGTH=$(printf "%02d" $M):$(printf "%02d" $S)
							;;
						*)
							LENGTH=''
							;;
					esac
					;;
			esac
		fi
		### E X E C ###
		[ ! "$EXEC" ] && EXEC="`date +%s%N` $ADR"
		#---
		if [ ${ADDMODE} = "next" ] && [ -s $WORKDIR/PLAYLIST_ALL ]; then #add the song after playing track
			read LINE_SELECTED < $WORKDIR/PLAYLIST_ALL
			LINE_NEW="|$LENGTH|$NAME|$ADR|$EXEC"
			grep -F -B 10000 "$LINE_SELECTED" $WORKDIR/tmp_playlist > $WORKDIR/tmp_add
			echo "$LINE_NEW" >> $WORKDIR/tmp_add
			grep -F -A 10000 "$LINE_SELECTED" $WORKDIR/tmp_playlist | tac | head -n -1 | tac >> $WORKDIR/tmp_add
			mv $WORKDIR/tmp_add $WORKDIR/tmp_playlist
		else #add at the end of list
			echo "|$LENGTH|$NAME|$ADR|$EXEC" >> $WORKDIR/tmp_playlist
		fi
		if [ -s $WORKDIR/AUTOPLAY -a $COUNT = 1 ]; then AUTOPLAY_ADR="$ADR"; fi

		#update progressbar
		echo $(($COUNT*100/$TOTAL)) > $WORKDIR/splash
		COUNT=$(($COUNT+1))
	done < $WORKDIR/songs_in_list
	( flock -e 201
		mv $WORKDIR/tmp_playlist $WORKDIR/playlist
	) 201>$WORKDIR/playlist.lockfile 
	[ -f $WORKDIR/gui_is_running ] && echo true | tee $WORKDIR/UPDATE_GUI $WORKDIR/UPDATE_PLAYLIST
	[ "$AUTOPLAY_ADR" ] && $APPDIR/func_player -play "$AUTOPLAY_ADR" -autoplay & #play first added track
	echo tail > $WORKDIR/ADDMODE  #add next track at the end of playqueue
	echo 100 > $WORKDIR/splash #be sure to close progress dialog
	$APPDIR/func -statusbar_playlist & #update statusbar
	;;
esac
